import traceback
from django.contrib import admin
from django.http import HttpResponse, HttpResponseRedirect
import requests
import urllib.parse  # 修改为正确的导入
import xlwt
from django.template.response import TemplateResponse  # 确保导入 TemplateResponse
from django.contrib import admin
from django.utils.html import format_html
from app.amazon_listing_interface import  fetch_amazon_data_interface
from app.api1 import AmazonService_pa
from app.intereface_amazon.databasemodel import Amazon_asinupload_xue_todb
from app.models import AmazonOrder2, AmazonOrderItem2, LogHistory  # 确保导入正确的模型
from django.contrib import admin
from .services import MessageSyncService
from django.utils.http import quote  # 添加这个导入
from django.db.models import Q
from django.contrib import messages
from datetime import datetime, timedelta, timezone
from django.contrib.admin import SimpleListFilter
from django.core.paginator import Paginator
from django.urls import path
from django.http import JsonResponse, FileResponse
from django.shortcuts import redirect, render
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User 
from django.utils.html import format_html, mark_safe
from django.urls import reverse
import pandas as pd
from sqlalchemy import create_engine, text
from sqlalchemy.exc import IntegrityError
import pandas as pd
from django.contrib import admin
from django import forms
from django.utils.html import format_html, mark_safe
from django.contrib import messages
from app.models import (
    CategoryDefault,
    CategoryXue,
    FollowPrice_lucas,
    PriceChange,
    RankChange,
    SkuKeywords_lucas,
    SkuKeywordsXue, 
    FollowPriceXue,
    asinsmonitor_xue,
    asinsupload_xue,
    upc_xue,
    ProductAnalysis,
    UserProfile,
    AmazonProductDisplay,
    Message,
    MessageThread,
    Buyer
)
import xlrd
import io
import os
import zipfile
from django.conf import settings
from django.templatetags.static import static
from django.contrib import messages
from django import forms
from django.db import models
from django.shortcuts import redirect
from django.shortcuts import redirect
from django.conf import settings
from .models import AmazonAppConfig, AmazonStore, Product2  
# 导入产品分析器 - 修正导入路径
# from walmartai import ProductCategoryAnalyzer
import random
import string

class ImportExcelForm(forms.Form):
    excel_file = forms.FileField(label='选择 Excel 文件', required=True)

# Register your models here.
admin.site.site_title = 'walmart上新系统'
admin.site.index_title = 'walmart上新索引'
#网页列标题
admin.site.site_header='walmart上新'
#网页标题
admin.site.site_title='walmart上新-信息管理'
#首页标语
admin.site.index_title = 'walmart上新-系统管理'
  
      
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.models import User
# admin.py (实现自定义菜单)# admin.py (修正中文变量名)
from django.contrib import admin
from django.urls import reverse
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from .models import AmazonStore, Buyer, MessageThread, Message
  
from .models import Buyer, Message, MessageThread

class BuyerAdmin(admin.ModelAdmin):
    list_display = ('id',)
    search_fields = ('id',)
@admin.register(Buyer)
 

class MessageThreadAdmin(admin.ModelAdmin):
    list_display = ('id'  ,'amazon_buyer_id','display_name')  # 确保 'buyer' 和 'message' 是 ForeignKey
    search_fields = ('id',)
@admin.register(MessageThread)
class MessageAdmin(admin.ModelAdmin):
    list_display = ('id',)  # 确保 'buyer' 是 ForeignKey
    search_fields = ('id',)
@admin.register(Message)  

class BaseAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        # 记录日志
        LogHistory.objects.create(
            obj=request.path,  # 记录访问的页面路径
            action='访问',  # 记录操作类型
            opdate=datetime.now(),  # 当前时间
            diskid=request.user.id if request.user.is_authenticated else None  # 记录用户 ID
        )
        return super().get_queryset(request)
 

@admin.register(AmazonOrder2)
class AmazonOrderAdmin(BaseAdmin):
    list_display = [
        'id',
        'amazon_order_id', 
        'formatted_date', 
        'order_status', 
        'fulfillment_channel', 
        'order_total_display',
        'order_items_display'  # 新增：显示订单明细
    ]
    list_filter = ['order_status', 'fulfillment_channel', 'is_prime', 'is_business_order']
    search_fields = ['amazon_order_id', 'buyer_email', 'shipping_address_city', 'shipping_address_state']
    readonly_fields = ['amazon_order_id', 'created_at', 'updated_at']
    date_hierarchy = 'purchase_date'
    
    # 添加自定义CSS和JavaScript
    class Media:
        css = {
            'all': ('admin/css/order_items.css',)
        }
        js = ('admin/js/order_items.js',)
    
    fieldsets = (
        ('订单基本信息', {
            'fields': (
                'amazon_order_id', 'seller_order_id', 'purchase_date', 
                'order_status', 'last_update_date'
            )
        }),
        ('订单明细', {
            'fields': (
                'order_total_amount', 'currency_code', 'number_of_items_shipped',
                'number_of_items_unshipped'
            )
        }),
        # ... 其他字段组 ...
    )
    
    def formatted_date(self, obj):
        if obj.purchase_date:
            return obj.purchase_date.strftime('%Y-%m-%d %H:%M')
        return '-'
    formatted_date.short_description = '购买日期'
    
    def order_total_display(self, obj):
        if obj.order_total_amount and obj.currency_code:
            return f"{obj.order_total_amount} {obj.currency_code}"
        return "-"
    order_total_display.short_description = "订单总额"
    
    # 增强版：可折叠的订单明细
    def order_items_display(self, obj):
        # 获取该订单的所有明细
        items = AmazonOrderItem2.objects.filter(order=obj)
        
        if not items.exists():
            return "无明细"
        
        # 构建HTML表格
        html = f'<div class="order-items-container" data-order-id="{obj.id}">'
        html += f'<button class="toggle-items-btn" onclick="toggleOrderItems({obj.id})">显示/隐藏明细</button>'
        html += f'<div id="order-items-{obj.id}" class="order-items-details" style="display:none;">'
        html += '<table class="order-items-table">'
        html += '<tr class="order-items-header">'
        html += '<th>ASIN</th>'
        html += '<th>SKU</th>'
        html += '<th>标题</th>'
        html += '<th>数量</th>'
        html += '<th>价格</th>'
        html += '</tr>'
        
        for item in items:
            html += '<tr>'
            html += f'<td>{item.asin}</td>'
            html += f'<td>{item.seller_sku or "-"}</td>'
            html += f'<td>{item.title or "-"}</td>'
            html += f'<td>{item.quantity_ordered}</td>'
            
            # 显示价格和货币
            price_display = "-"
            if item.item_price and item.item_price_currency:
                price_display = f"{item.item_price} {item.item_price_currency}"
            html += f'<td>{price_display}</td>'
            
            html += '</tr>'
        
        html += '</table>'
        html += '</div>'
        html += '</div>'
        
        return format_html(html)
    order_items_display.short_description = "订单明细"

# 保留AmazonOrderItem2的注册，但可以隐藏它
@admin.register(AmazonOrderItem2)
class AmazonOrderItemAdmin(BaseAdmin):
    list_display = ['order_item_id', 'order_link', 'asin', 'title', 'quantity_ordered', 'item_price_display']
    search_fields = ['order_item_id', 'asin', 'seller_sku', 'title', 'order__amazon_order_id']
    list_filter = ['is_gift', 'condition']
    readonly_fields = ['order', 'order_item_id']
    
    def order_link(self, obj):
        try:
            url = f"/admin/app/amazonorder2/{obj.order.id}/change/"
            return format_html('<a href="{}">{}</a>', url, obj.order.amazon_order_id)
        except Exception as e:
            return "-"
    order_link.short_description = '订单ID'
    
    def item_price_display(self, obj):
        if obj.item_price and obj.item_price_currency:
            return f"{obj.item_price} {obj.item_price_currency}"
        return "-"
    item_price_display.short_description = '商品价格'
    
    # 隐藏此模型，但保留注册
    def get_model_perms(self, request):
        """仅隐藏菜单，但允许通过反向关联访问数据"""
        perms = super().get_model_perms(request)
        perms.pop('add', None)
        perms.pop('change', None)
        perms.pop('delete', None)
        return perms


class CustomUserCreationForm(UserCreationForm):
    epid = forms.CharField(max_length=64, required=False, label='部门编号', 
                           help_text='请输入用户所属的部门编号', initial='default')
    
    class Meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'epid')
        
class CustomUserChangeForm(UserChangeForm):
    epid = forms.CharField(max_length=64, required=False, label='部门编号')
    
    class Meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'epid')
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 如果用户已存在，从关联的profile获取epid值
        if self.instance and hasattr(self.instance, 'profile'):
            self.fields['epid'].initial = self.instance.profile.epid
class DepartmentFilteredModelAdmin(BaseAdmin):
     
    
    def get_queryset(self, request):
        """默认只显示用户所在部门的数据"""
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            # 超级用户可以看到所有数据
            return qs
        
        # 普通用户只能看到自己部门的数据
        if hasattr(request.user, 'profile'):
            return qs.filter(epid=request.user.profile.epid)
        return qs.none()  # 如果用户没有部门信息，则不显示任何数据
    
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_model(request, obj, form, change)
    
    def get_readonly_fields(self, request, obj=None):
        """设置部门字段为只读"""
        readonly_fields = list(super().get_readonly_fields(request, obj))
        if obj and not request.user.is_superuser:  # 编辑现有对象且不是超级用户
            if 'epid' not in readonly_fields:
                readonly_fields.append('epid')
        return readonly_fields


@admin.register(CategoryDefault)
class CategoryDefaultAdmin(DepartmentFilteredModelAdmin):
    list_display = ('label', 'inputvalue', 'input_type', 'platform', 'epid', 'created_at', 'updated_at')
    list_filter = ('input_type', 'platform')
    search_fields = ('label', 'inputvalue')
    readonly_fields = ('created_at', 'updated_at')
    exclude = ['epid']
    fieldsets = (
        ('产品类目默认信息', {
            'fields': ( 'label', 'inputvalue', 'input_type', 'platform', )
     
        }), 
        )
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_model(request, obj, form, change)
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display

# @admin.register(ProductAnalysis)
# class ProductAnalysisAdmin(DepartmentFilteredModelAdmin):
#     list_display = ('productid', 'market_demand', 'competition_level', 'profitability', 
#                    'surge_index', 'is_surging', 'analysis_date')
#     list_filter = ('is_surging', 'analysis_date')
#     search_fields = ('productid', 'optimized_title')
#     readonly_fields = ('created_at', 'updated_at')
#     ordering = ('-analysis_date',)
    
#     fieldsets = (
#         ('基本信息', {
#             'fields': ('productid', 'analysis_date', 'epid')
#         }),
#         ('市场指标', {
#             'fields': ('market_demand', 'competition_level', 'profitability', 'growth_potential')
#         }),
#         ('变化趋势', {
#             'fields': ('surge_index', 'rank_change', 'sales_change', 'review_change', 'is_surging')
#         }),
#         ('优化建议', {
#             'fields': ('optimized_title', 'optimized_bullets', 'keyword_suggestions')
#         }),
#         ('其他信息', {
#             'fields': ('confidence_score', 'created_at', 'updated_at')
#         }),
#     )
    
#     # 完全重写get_queryset方法，不使用select_related
#     def get_queryset(self, request):
#         """重写查询集方法，不使用select_related"""
#         # 直接从DepartmentFilteredModelAdmin获取查询集
#         return super().get_queryset(request)
    
#     # 可选：如果需要显示关联产品信息，添加自定义方法
#     def get_product_info(self, obj):
#         """获取关联产品信息（不使用select_related）"""
#         from .models import ProductXue
#         product = ProductXue.objects.filter(productid=obj.productid).first()
#         if product:
#             return f"{product.title[:30]}..." if product.title else "-"
#         return "-"
#     get_product_info.short_description = "产品信息"
    
#     def get_readonly_fields(self, request, obj=None):
#         """创建时所有字段可编辑，编辑时部分字段只读"""
#         readonly_fields = list(super().get_readonly_fields(request, obj))
#         if obj:  # 编辑现有对象
#             if 'productid' not in readonly_fields:
#                 readonly_fields.append('productid')
#             if 'analysis_date' not in readonly_fields:
#                 readonly_fields.append('analysis_date')
#         return readonly_fields
    
#     def has_delete_permission(self, request, obj=None):
#         """禁止删除分析记录"""
#         return False
    
#     def has_add_permission(self, request):
#         """禁止手动添加分析记录"""
#         return False
    
#     def get_actions(self, request):
#         """移除删除操作"""
#         actions = super().get_actions(request)
#         if 'delete_selected' in actions:
#             del actions['delete_selected']
#         return actions
      
class upc_xueAdmin(DepartmentFilteredModelAdmin):
    list_display = ['id', 'upc', 'epid', 'created_at', 'upload_at']
    list_filter = ['created_at']
    search_fields = ['upc']
    list_per_page = 20  
    change_list_template = "admin/app_upc_xue_changelist.html"  # 自定义模板
    exclude = ['epid']
    fieldsets = (
        ('upc信息', {
            'fields': ( 'upc', )
     
        }), 
        )
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_model(request, obj, form, change)
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display

    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return True

    def has_view_permission(self, request, obj=None):
        return True

    def has_add_permission(self, request):
        return True

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('import_excel/', self.admin_site.admin_view(self.import_excel), name='import_excel'),
        ]
        return custom_urls + urls
    def import_excel(self, request):
        if request.method == 'POST':
            form = ImportExcelForm(request.POST, request.FILES)
            if form.is_valid():
                excel_file = request.FILES['excel_file']
                try:
                    df = pd.read_excel(excel_file)
                    total_rows = len(df)
                    upc_list=[]
                    for index,row  in df.iterrows():
                        
                            upcint = 0
                            value_to_insert = row[1]
                            if isinstance(value_to_insert, (int, float)):
                                upcint = int(value_to_insert)
                            print(index,upcint,'/',total_rows)  
                            upc_list.append({'upc':upcint,'epid':request.user.profile.epid})
                 
                    # 使用 bulk_create 批量创建记录
                    sql='''
                          insert into  app_upc_xue(upc,epid,created_at) values(:upc,:epid,now() )  on DUPLICATE key update   upc=:upc,epid=:epid,created_at=now() 
                        '''
                    db_config = {
                        "user": "root",
                        "password": "Zb_200407",
                        "host": "gz-cdb-d4j7h16x.sql.tencentcdb.com",
                        "database": "walmart",
                        "port": 22333
                    }
                    connection_string = (
                        f"mysql+pymysql://{db_config['user']}:{db_config['password']}"
                        f"@{db_config['host']}:{db_config['port']}/{db_config['database']}?connect_timeout=10"
                    )
                    engine1  = create_engine(connection_string,pool_recycle=3600)
                    with engine1.connect() as connection:
                        connection.execute(text(sql), upc_list)
                        connection.commit()         
                
                    messages.success( request,  f'成功处理第 {index+1} 到 {upcint} 记录' )
                    return self.response_change(request)
                except Exception as e:
                    messages.error(      request, f'处理第 {index+1} 到 {upcint}  记录时出错: {str(e)}'  )
                    traceback.print_exc()

                    messages.success(request, 'Excel 文件导入成功')
                    # return self.response_change(request)
                    return redirect('..')
                except Exception as e:
                    messages.error(request, f'第 {index + 1} 行数据插入/更新失败: {e}')
                    traceback.print_exc()

        else:
            form = ImportExcelForm()

        context = {
            'form': form,
        }
        return TemplateResponse(request, "admin/import_excel.html", context)
     
admin.site.register(upc_xue, upc_xueAdmin)
class SkuKeyXueAdmin(DepartmentFilteredModelAdmin):
    list_display = [
        'keywords', 'username', 'epid', 'opdate', 'download_date', 'shop_type',
        'get_row_actions'
    ]
    list_display_links = ('keywords','username')
    search_fields = ('keywords', 'username', 'shop_type')
    list_filter = ['keywords', 'username', 'shop_type']
    list_per_page = 20
    save_as = True
    actions = ['export_current_page']
    actions_on_top = True
    sort_by = ['keywords']
    exclude = ['epid']
    fieldsets = (
        ('关键词信息', {
            'fields': ('keywords', 'username', 'shop_type')
        }),
        ('其他信息', {
            'fields': ('download_date',  )
        }),
    )
     
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_model(request, obj, form, change)
    
    def get_row_actions(self, obj):
        """获取行操作按钮"""
        if not obj:
            return ''
            
        # 获取各种URL
        change_url = f'/admin/app/skukeywords/{obj.id}/change/'
        delete_url = f'/admin/app/skukeywords/{obj.id}/delete/'
        history_url =  f'/admin/skukeywords/skukeywords_history/?keywords={obj.keywords}'
        history_url = f'/admin/app/skukeywords_history/?keywords={obj.keywords}'


        # follow_price_url = f'/admin/app/skukeywordsprice/?keywords_id={obj.keywords}'   
        follow_price_url = f'/admin/skukeywords/skukeywordsanotherproxy/?keywords={obj.keywords}'
        follow_price_url = f'/jobs/followprice/query1/?keywords={obj.keywords}'
        follow_price_url = f'/admin/skukeywords/skukeywordsanotherproxy/?keywords={obj.keywords}'
        follow_price_url = f'/admin/app/followprice/?q={obj.keywords}'




        # 使用format_html确保HTML安全性
        return format_html(
            '<a class="button" href="{}">编辑</a>&nbsp;'
            '<a class="button" href="{}">删除</a>&nbsp;'
            '<a class="button" href="{}">关键词下载历史</a>&nbsp;'
            '<a class="button" href="{}">去看下载产品并处理</a>',
            change_url,
            delete_url,
            history_url,
            follow_price_url
        )
    
    get_row_actions.short_description = '操作'
    get_row_actions.allow_tags = True

    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return True

    def has_view_permission(self, request, obj=None):
        return True

    def has_add_permission(self, request):
        return True

    def export_current_page(self, request, queryset):
        """导出当前页数据"""
        response = HttpResponse(content_type='application/ms-excel')
        response['Content-Disposition'] = f'attachment; filename="skukeywords_currentpage_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xls"'
        
        wb = xlwt.Workbook(encoding='utf-8')
        ws = wb.add_sheet('SkuKeywords')
        
        # 自动生成列名
        row_num = 0
        fields = [field for field in self.model._meta.fields if field.name in self.list_display[:-1]]  # 排除 get_row_actions
        columns = [field.verbose_name or field.name for field in fields]
        
        # 设置列宽
        for i in range(len(columns)):
            ws.col(i).width = 256 * 20  # 20个字符宽度
        
        # 设置标题样式
        header_style = xlwt.XFStyle()
        header_style.font.bold = True
        
        for col_num, column_title in enumerate(columns):
            ws.write(row_num, col_num, column_title, header_style)
        
        # Write data rows
        for row in queryset:
            row_num += 1
            for col_num, field in enumerate(fields):
                value = getattr(row, field.name)
                ws.write(row_num, col_num, value)
        
        wb.save(response)
        return response
    
    export_current_page.short_description = "导出当前页数据"

    def get_fields(self, request, obj=None):
        """获取表单字段"""
        fields = super().get_fields(request, obj)
        if 'username' not in fields:
            fields = ['username'] + list(fields)
        return fields
 
     

    def formfield_for_dbfield(self, db_field, request, **kwargs):
        """设置表单字段的初始值"""
        field = super().formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'username':
            field.initial = request.user.username

        return field

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['keywords'].required = True  # 设置为必填
        form.base_fields['keywords'].label = format_html(
            '{}<span style="color: red;">*</span>', 
            'Keywords'
        )  # 添加红色星号
        return form

admin.site.register(SkuKeywordsXue, SkuKeyXueAdmin) 
 
class SkuKeyAdmin_lucas(BaseAdmin):
    list_display = [
        'keywords',  'ebay', 'ali','amz','username', 'opdate','download_date',
        'get_row_actions'
    ]
    list_display_links = ('keywords','username')
    search_fields = ( 'keywords', 'username')
    list_filter = ['keywords', 'username', 'ebay', 'ali', 'amz']
    list_per_page = 20
    save_as = True
    actions = ['export_current_page']
    actions_on_top = True
    sort_by = ['keywords']
    
    def get_row_actions(self, obj):
        """获取行操作按钮"""
        if not obj:
            return ''
            
        # 获取各种URL
        change_url = f'/admin/app/skukeywords/{obj.id}/change/'
        delete_url = f'/admin/app/skukeywords/{obj.id}/delete/'
        history_url =  f'/admin/skukeywords/skukeywords_history/?keywords={obj.keywords}'
        history_url = f'/admin/app/skukeywords_history/?keywords={obj.keywords}'


        # follow_price_url = f'/admin/app/skukeywordsprice/?keywords_id={obj.keywords}'   
        follow_price_url = f'/admin/skukeywords/skukeywordsanotherproxy/?keywords={obj.keywords}'
        follow_price_url = f'/jobs/followprice/query1/?keywords={obj.keywords}'
        follow_price_url = f'/admin/skukeywords/skukeywordsanotherproxy/?keywords={obj.keywords}'
        follow_price_url = f'/admin/app/followprice/?q={obj.keywords}'




        # 使用format_html确保HTML安全性
        return format_html(
            '<a class="button" href="{}">编辑</a>&nbsp;'
            '<a class="button" href="{}">删除</a>&nbsp;'
            '<a class="button" href="{}">关键词下载历史</a>&nbsp;'
            '<a class="button" href="{}">去看下载产品并处理</a>',
            change_url,
            delete_url,
            history_url,
            follow_price_url
        )
    
    get_row_actions.short_description = '操作'
    get_row_actions.allow_tags = True

    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return True

    def has_view_permission(self, request, obj=None):
        return True

    def has_add_permission(self, request):
        return True

    def export_current_page(self, request, queryset):
        """导出当前页数据"""
        response = HttpResponse(content_type='application/ms-excel')
        response['Content-Disposition'] = f'attachment; filename="skukeywords_currentpage_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xls"'
        
        wb = xlwt.Workbook(encoding='utf-8')
        ws = wb.add_sheet('SkuKeywords')
        
        # 自动生成列名
        row_num = 0
        fields = [field for field in self.model._meta.fields if field.name in self.list_display[:-1]]  # 排除 get_row_actions
        columns = [field.verbose_name or field.name for field in fields]
        
        # 设置列宽
        for i in range(len(columns)):
            ws.col(i).width = 256 * 20  # 20个字符宽度
        
        # 设置标题样式
        header_style = xlwt.XFStyle()
        header_style.font.bold = True
        
        for col_num, column_title in enumerate(columns):
            ws.write(row_num, col_num, column_title, header_style)
        
        # Write data rows
        for row in queryset:
            row_num += 1
            for col_num, field in enumerate(fields):
                value = getattr(row, field.name)
                ws.write(row_num, col_num, value)
        
        wb.save(response)
        return response
    
    export_current_page.short_description = "导出当前页数据"

    def get_fields(self, request, obj=None):
        """获取表单字段"""
        fields = super().get_fields(request, obj)
        if 'username' not in fields:
            fields = ['username'] + list(fields)
        return fields

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if hasattr(request.user, 'userprofile') and not request.user.userprofile.is_leader:
            return qs.filter(username=request.user.username)
        return qs

    def save_model(self, request, obj, form, change):
        if not change:  # 只在新增时设置 username
            obj.username = request.user.username
        obj.save()

    def get_readonly_fields(self, request, obj=None):
        """动态设置只读字段"""
        if obj:  # 编辑时
            return self.readonly_fields + ('username',)
        return self.readonly_fields

    def formfield_for_dbfield(self, db_field, request, **kwargs):
        """设置表单字段的初始值"""
        field = super().formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'username':
            field.initial = request.user.username

        return field

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['keywords'].required = True  # 设置为必填
        form.base_fields['keywords'].label = format_html(
            '{}<span style="color: red;">*</span>', 
            'Keywords'
        )  # 添加红色星号
        return form

admin.site.register(SkuKeywords_lucas, SkuKeyAdmin_lucas) 

class FollowPriceAdmin_lucas(BaseAdmin):
    list_display = [
        'id', 'storename', 'shop_type', 'itemid', 'keywords', 'display_pic', 'username', 'title', 'link',
        'price', 'salesvolume', 'price2', 'salesvolume2', 'display_pic2', 'lowvalue', 'opdate', 'productid'
    ]
    list_editable = ('itemid',)
    list_display_links = ('id', 'storename')
    search_fields = ('id', 'shop_type', 'username', 'keywords','link', 'title', 'itemid', 'productid', 'opdate')

    def display_pic(self, obj):
        """Display the product pic in the admin list view with hover effect."""
        if obj.pic:
            return format_html(
                '<div style="position: relative; display: inline-block;">'
                '<img src="{}" style="max-height: 50px; transition: transform 0.2s; z-index: 1;" class="product-pic" />'
                '<style>'
                '.product-pic:hover {{ transform: scale(12); z-index: 10000; position: relative; }}'
                '</style>'
                '</div>',
                obj.pic
            )
        return "No pic"
    display_pic.short_description = "产品图片"

    def display_pic2(self, obj):
        if obj.pic2:
            return format_html(
                '<div style="position: relative; display: inline-block;">'
                '<img src="{}" style="max-height: 50px; transition: transform 0.2s; z-index: 1;" class="product-pic" />'
                '<style>'
                '.product-pic:hover {{ transform: scale(12); z-index: 10000; position: relative; }}'
                '</style>'
                '</div>',
                obj.pic2
            )
        return "-"
    display_pic2.short_description = '图片2'

    def get_paginator(self, request, queryset, per_page):
        from django.core.paginator import Paginator
        return Paginator(queryset, 20)
    
    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return False

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['itemid'].required = False
        return form

# 注册到 admin
admin.site.register(FollowPrice_lucas, FollowPriceAdmin_lucas) 
class FollowPriceXueAdmin(DepartmentFilteredModelAdmin):
    # 添加批量删除动作
    actions = ['delete_selected', 'mark_as_shippable', 'mark_as_unshippable']
    
    # 修改删除权限
    def has_delete_permission(self, request, obj=None):
        # 允许超级用户删除
        if request.user.is_superuser:
            return True
        # 允许有删除权限的用户
        return request.user.has_perm('app.delete_followpricexue')
    
    list_display = [
        'id',
        'short_title',
        'short_link',
        *[f'short_detail{i}' for i in range(1,6)],
        'can_pubished', 'display_pic', 'storename', 'productid', 'epid',
        'rating', 'reviews_count', 'sales_info', 'brand', 'delivery_info', 
        'category', 'keywords', 'username', 'title', 'price', 'salesvolume', 
        'capturedatetowalmart', 'opdate'
    ]

    list_display_links = ('id', 'storename','keywords')
    search_fields = ('id', 'username', 'keywords','link', 'title', 'itemid', 'opdate')
    list_filter = ('shop_type', 'storename', 'can_pubished')
    
    # Pagination
    list_per_page = 200
    
    exclude = ['epid']
    
    # 或者使用fieldsets定义表单中显示的字段组，不包含epid
    fieldsets = (
        ('基本信息', {
            'fields': (  'title', 'link', 'productid', 'storename', 'rating', 
                      'reviews_count', 'brand', 'price', 'category', 'keywords', 'username')
        }),
        ('详细信息', {
            'fields': ('detail1', 'detail2', 'detail3', 'detail4', 'detail5',
                      'can_pubished', 'sales_info', 'delivery_info')
        }),
        ('其他信息', {
            'fields': ('salesvolume', 'capturedatetowalmart', 'shop_type')
        })
    )
    
    # 2. 在列表显示中对非管理员隐藏epid字段
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display
    
    # 3. 确保保存时设置epid (DepartmentFilteredModelAdmin已实现，但我们可以重新确认)
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_mod

    def display_pic(self, obj):
        """显示所有图片"""
        images = []
        
        # 处理主图
        if obj.main_image:
            full_url = self.build_full_url(obj.main_image)  # 路径转完整URL
            images.append(self.image_html(full_url))
        
        # 处理附加图片
        for i in range(1, 8):
            img_path = getattr(obj, f'image{i}', '')
            if img_path:
                full_url = self.build_full_url(img_path)
                images.append(self.image_html(full_url))
        
        return format_html(
            '<div style="display: flex; overflow-x: auto;">{}</div>',
            mark_safe(''.join(images)) if images else '暂无图片'
        )

    def build_full_url(self, path):
        """构建完整图片URL"""
        # 根据存储方案选择
        if path.startswith('http'):
            return path  # 已经是完整URL
        else:
            return f'{settings.MEDIA_URL}{path}'  # 拼接媒体路径

    def image_html(self, url):
        """生成图片HTML片段"""
        return format_html(
            '<div class="image-container">'
            '<img src="{}" style="{}" />'
            '</div>',
            url,
            'max-height: 50px; margin-right: 5px;'
        )

    def get_paginator(self, request, queryset, per_page):
        from django.core.paginator import Paginator
        return Paginator(queryset, 20)
    
    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return True

    def can_pubished_display(self, obj):
        """Format the display of the shipping status"""
        if obj.can_pubished:
            return format_html('<span style="color: green; font-weight: bold;">可上新</span>')
        else:
            return format_html('<span style="color: red;">不可上新</span>')
    can_pubished_display.short_description = "发货状态"
    can_pubished_display.admin_order_field = 'can_pubished'
    
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('mark-shippable/', self.admin_site.admin_view(self.mark_shippable_view), name='lasqiuzhangorder_mark-shippable'),
            path('mark-unshippable/', self.admin_site.admin_view(self.mark_unshippable_view), name='lasqiuzhangorder_mark-unshippable'),
        ]
        return custom_urls + urls
    
    def mark_as_shippable(self, request, queryset):
        """将选中记录设置为可上新"""
        updated = queryset.update(can_pubished=1)
        self.message_user(request, f'成功将 {updated} 条订单设为可上新状态', messages.SUCCESS)
    mark_as_shippable.short_description = format_html('<span style="color: green; font-weight: bold;">设为可上新</span>')
    
    def mark_as_unshippable(self, request, queryset):
        """将选中记录设置为不可上新"""
        updated = queryset.update(can_pubished=0)
        self.message_user(request, f'成功将 {updated} 条订单设为不可上新状态', messages.SUCCESS)
    mark_as_unshippable.short_description = format_html('<span style="color: red; font-weight: bold;">设为不可上新</span>')
    
    def mark_shippable_view(self, request):
        """处理批量设为可上新的自定义视图"""
        selected = request.POST.getlist('_selected_action')
        if not selected:
            self.message_user(request, '未选择任何订单', messages.WARNING)
            return HttpResponseRedirect(request.META['HTTP_REFERER'])
        
        queryset = self.model.objects.filter(pk__in=selected)
        return self.mark_as_shippable(request, queryset)
    
    def mark_unshippable_view(self, request):
        """处理批量设为不可上新的自定义视图"""
        selected = request.POST.getlist('_selected_action')
        if not selected:
            self.message_user(request, '未选择任何订单', messages.WARNING)
            return HttpResponseRedirect(request.META['HTTP_REFERER'])
        
        queryset = self.model.objects.filter(pk__in=selected)
        return self.mark_as_unshippable(request, queryset)
    
    def changelist_view(self, request, extra_context=None):
        """自定义列表视图"""
        extra_context = extra_context or {}
        # Removed show_shippable_buttons flag to hide the custom buttons
        return super().changelist_view(request, extra_context=extra_context)

    def _truncate_field(self, value, max_length=20):
        """严格截断字段到指定长度"""
        if not value:
            return ''
        
        # 转换为字符串并去除前后空格
        str_value = str(value).strip()
        
        # 精确长度控制
        truncated = str_value[:max_length]  # 严格截取前20个字符
        if len(str_value) > max_length:
            return format_html(
                '<span title="完整内容：{}" class="truncated-field">{}</span>',
                str_value,
                f"{truncated}...."  # 显示20字符+4个点
            )
        return truncated  # 不足20字符直接返回

    # 标题处理
    def short_title(self, obj):
        return self._truncate_field(obj.title, 20)
    short_title.short_description = '标题'
    short_title.admin_order_field = 'title'

    # 链接处理
    def short_link(self, obj):
        return self._truncate_field(obj.link, 20)
    short_link.short_description = '链接'
    short_link.admin_order_field = 'link'

    def get_truncated_detail(self, obj, field_number):
        """通用详情处理"""
        field_name = f'detail{field_number}'
        value = getattr(obj, field_name, '')
        return self._truncate_field(value, 20)

    # 为每个字段生成独立方法
    for i in range(1, 6):
        def closure(field_num):
            def method(self, obj):
                return self.get_truncated_detail(obj, field_num)
            method.short_description = f'详情{field_num}'
            method.__name__ = f'short_detail{field_num}'
            return method
        locals()[f'short_detail{i}'] = closure(i)

# 注册到 admin
admin.site.register(FollowPriceXue, FollowPriceXueAdmin)



class SkuKeyHistoryAdmin(BaseAdmin):
    list_display = ['sku', 'chargeman', 'keywords',  'username','fromprice','toprice','ebay',
                    'ali','opdate']  # 在列表页面显示的字段
    search_fields = ('sku', 'keywords', 'chargeman')
    list_per_page = 20
    list_filter = ['keywords']
    save_as = True
    actions_on_top = True
    sort_by = ['keywords', 'sku']
    def has_add_permission(self, request):
        return False
    def has_delete_permission(self, request, obj = None):
        return False
    def has_change_permission(self, request, obj = None):
        return False
    def get_paginator(self, request, queryset, per_page):
        return Paginator(queryset, 20)
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # Get keywords from URL parameters
        # keywords = request.GET.get('keywords')
        # if keywords:
        #     qs = qs.filter(keywords__icontains=keywords)
        if hasattr(request.user, 'userprofile') and not request.user.userprofile.is_leader:
            qs = qs.filter(username=request.user.username)
        return qs
    def save_model(self, request, obj, form, change):
        if not obj.username:
            obj.username = request.user.username
        obj.save()
 

class RatesAdmin(BaseAdmin):
    list_display = ['currency_simplename','currency_name',                     'opdate']  # 在列表页面显示的字段

    search_fields = ('currency_simplename','currency_name', 'opdate')
    def has_add_permission(self, request):
        return False
    def has_delete_permission(self, request, obj = None):
        return False
    def has_change_permission(self, request, obj = None):
        return True
# admin.site.register(Rates, RatesAdmin)

class CrawlExceptAdmin(admin.ModelAdmin):
    list_display = ['shop_type', 'keywords', 'exceptcon','opdate']  # 在列表页面显示的字段

    search_fields = ('shop_type', 'keywords', 'exceptcon','opdate')
    def has_add_permission(self, request):
        return False
    def has_delete_permission(self, request, obj = None):
        return False
    def has_change_permission(self, request, obj = None):
        return False
 

class CustomAdminSite(admin.AdminSite):
    class Media:
        css = {
            'all': (static('css/admin_custom.css'),)
        }
 
# 以下是新增的关键词分析功能代码

class KeywordAnalysisForm(forms.Form):
    """关键词分析表单"""
    keyword = forms.CharField(
        label='关键词', 
        max_length=100, 
        help_text='输入产品类别关键词，如"home decor"、"家居装饰"等'
    )
    days = forms.IntegerField(
        label='数据天数', 
        initial=30, 
        min_value=1, 
        max_value=365,
        help_text='分析最近多少天的数据'
    )
    limit = forms.IntegerField(
        label='数据条数', 
        initial=1000, 
        min_value=100, 
        max_value=5000,
        help_text='最多分析多少条记录'
    )
    export_format = forms.ChoiceField(
        label='导出格式',
        choices=[
            ('zip', 'ZIP归档(包含所有图表和日志)'),
            ('pdf', 'PDF报告(单文档)'),
            ('excel', 'Excel表格(数据摘要)')
        ],
        initial='zip',
        help_text='选择报告导出格式'
    )

# 添加一个虚拟模型类用于创建Admin页面
class ProductKeywordAnalysis(BaseAdmin):
    """用于关键词分析的虚拟模型"""
    class Meta:
        verbose_name = '产品关键词分析'
        verbose_name_plural = '产品关键词分析'
        # 这是一个虚拟模型，不会创建数据库表
        managed = False
        app_label = 'app'
        db_table = 'product_keyword_analysis'

# class ProductKeywordAnalysisAdmin(admin.ModelAdmin):
#     """产品关键词分析管理界面"""
    
#     # 设置列表显示，不显示任何字段
#     list_display = []
    
#     def get_urls(self):
#         """添加自定义URL"""
#         urls = super().get_urls()
#         custom_urls = [
#             path(
#                 'keyword_analysis/', 
#                 self.admin_site.admin_view(self.keyword_analysis_view), 
#                 name='product-keyword-analysis'
#             ),
#             path(
#                 'download_report/<str:report_dir>/<str:format>/',
#                 self.admin_site.admin_view(self.download_report_view),
#                 name='download-report'
#             ),
#         ]
#         return custom_urls + urls
    
#     def changelist_view(self, request, extra_context=None):
#         """重写列表视图，直接重定向到关键词分析页面"""
#         return HttpResponseRedirect(
#             reverse('admin:product-keyword-analysis')
#         )
    
#     def download_report_view(self, request, report_dir, format):
#         """下载报告视图"""
#         # 报告目录就是media/reports
#         base_dir = getattr(settings, 'MEDIA_ROOT', '')
#         report_path = os.path.join(base_dir, 'reports')
        
#         if not os.path.exists(report_path):
#             messages.error(request, f"报告目录不存在")
#             return HttpResponseRedirect(reverse('admin:product-keyword-analysis'))
            
#         if format == 'zip':
#             # 创建ZIP文件
#             # 使用report_dir作为前缀来过滤文件
#             zip_filename = f"{report_dir}.zip"
#             zip_path = os.path.join(os.path.dirname(report_path), zip_filename)
            
#             with zipfile.ZipFile(zip_path, 'w') as zipf:
#                 for root, dirs, files in os.walk(report_path):
#                     for file in files:
#                         if file.startswith(report_dir):  # 只包含匹配前缀的文件
#                             file_path = os.path.join(root, file)
#                             arcname = os.path.basename(file_path)  # 只保留文件名
#                             zipf.write(file_path, arcname)
            
#             # 提供下载
#             with open(zip_path, 'rb') as f:
#                 response = HttpResponse(f.read(), content_type='application/zip')
#                 response['Content-Disposition'] = f'attachment; filename="{zip_filename}"'
#                 return response
                
#         elif format == 'pdf':
#             # 查找PDF文件
#             pdf_files = [f for f in os.listdir(report_path) if f.endswith('.pdf') and f.startswith(report_dir)]
#             if pdf_files:
#                 pdf_path = os.path.join(report_path, pdf_files[0])
#                 with open(pdf_path, 'rb') as f:
#                     response = HttpResponse(f.read(), content_type='application/pdf')
#                     response['Content-Disposition'] = f'attachment; filename="{pdf_files[0]}"'
#                     return response
#             else:
#                 messages.error(request, "未找到PDF报告文件")
                
#         elif format == 'excel':
#             # 查找Excel文件
#             excel_files = [f for f in os.listdir(report_path) if (f.endswith('.xlsx') or f.endswith('.xls')) and f.startswith(report_dir)]
#             if excel_files:
#                 excel_path = os.path.join(report_path, excel_files[0])
#                 with open(excel_path, 'rb') as f:
#                     if excel_path.endswith('.xlsx'):
#                         content_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
#                     else:
#                         content_type = 'application/vnd.ms-excel'
#                     response = HttpResponse(f.read(), content_type=content_type)
#                     response['Content-Disposition'] = f'attachment; filename="{excel_files[0]}"'
#                     return response
#             else:
#                 messages.error(request, "未找到Excel报告文件")
        
#         # 如果没有找到对应格式的文件
#         return HttpResponseRedirect(reverse('admin:product-keyword-analysis'))
    
#     def keyword_analysis_view(self, request):
#         """关键词分析视图"""
#         context = {
#             'title': '产品关键词分析',
#             'opts': self.model._meta,
#             'has_report': False,
#             'report_files': None,
#         }
#         keyword=''
#         if request.method == 'POST':
#             form = KeywordAnalysisForm(request.POST)
#             if form.is_valid():
#                 keyword = form.cleaned_data['keyword']
#                 days = form.cleaned_data['days']
#                 limit = form.cleaned_data['limit']
#                 export_format = form.cleaned_data['export_format']
                
#                 try:
#                     # 获取当前用户的部门编号
#                     epid = request.user.profile.epid if hasattr(request.user, 'profile') else 'default'
                    
#                     # 创建分析器并生成报告，传递用户部门ID
#                     analyzer = ProductCategoryAnalyzer(category=keyword, epid=epid)
                    
#                     # 确保报告目录存在
#                     media_root = getattr(settings, 'MEDIA_ROOT', '')
#                     media_reports_dir = os.path.join(media_root, 'reports')
#                     os.makedirs(media_reports_dir, exist_ok=True)
                    
#                     # 设置媒体URL
#                     if hasattr(settings, 'MEDIA_URL'):
#                         media_url = settings.MEDIA_URL.rstrip('/')
#                     else:
#                         media_url = '/media'
                    
#                     # 创建时间戳前缀，用于后续匹配文件
#                     timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
#                     file_prefix = f"{analyzer.category_slug}_{timestamp}_"
                    
#                     # 生成报告
#                     success = analyzer.generate_report(days=days, limit=limit)
                    
#                     if success:
#                         # 报告生成成功
#                         report_dir = analyzer.report_dir
#                         report_files = []
#                         chart_files = []
#                         data_files = []
                        
#                         # 获取报告目录中的文件列表
#                         for root, dirs, files in os.walk(report_dir):
#                             for file in files:
#                                 # 构建简单的相对路径
#                                 file_url = f"{media_url}/reports/{file}"
                                
#                                 # 分类文件
#                                 file_info = {
#                                     'name': file,
#                                     'path': file,
#                                     'url': file_url
#                                 }
                                
#                                 if file.endswith(('.png', '.jpg')):
#                                     chart_files.append({**file_info, 'type': 'chart'})
#                                 elif file.endswith(('.pdf', '.xlsx', '.csv')):
#                                     data_files.append({**file_info, 'type': 'data'})
                                
#                                 report_files.append(file_info)
                        
#                         # 找到主要图表 - 使用时间戳前缀匹配最新生成的文件
#                         price_chart = next((f for f in chart_files if 'price_distribution' in f['name'] and f['name'].startswith(file_prefix)), None)
#                         price_ranges_chart = next((f for f in chart_files if 'price_ranges' in f['name'] and f['name'].startswith(file_prefix)), None)
#                         rating_chart = next((f for f in chart_files if 'rating_distribution' in f['name'] and f['name'].startswith(file_prefix)), None)
#                         rating_price_chart = next((f for f in chart_files if 'price_vs_rating' in f['name'] and f['name'].startswith(file_prefix)), None)
#                         wordcloud = next((f for f in chart_files if 'title_wordcloud' in f['name'] and f['name'].startswith(file_prefix)), None)
#                         top_keywords_chart = next((f for f in chart_files if 'top_keywords' in f['name'] and f['name'].startswith(file_prefix)), None)
#                         sentiment_chart = next((f for f in chart_files if 'sentiment_analysis' in f['name'] and f['name'].startswith(file_prefix)), None)
                        
#                         # 获取日志数据
#                         log_file = os.path.join(report_dir, f"{file_prefix}analysis.log")
#                         log_summary = ""
#                         if os.path.exists(log_file):
#                             try:
#                                 with open(log_file, 'r', encoding='utf-8') as f:
#                                     log_content = f.readlines()
#                                     # 提取关键统计数据
#                                     stats_lines = []
#                                     for line in log_content:
#                                         if "平均价格:" in line or "价格中位数:" in line or "平均评分:" in line or \
#                                            "平均评论数:" in line or "前50个关键词:" in line or "平均情感得分:" in line:
#                                             stats_lines.append(line.strip())
                                    
#                                     log_summary = "\n".join(stats_lines)
#                             except Exception as e:
#                                 log_summary = f"读取日志文件时出错: {str(e)}"
                        
#                         # 读取Excel数据以显示在页面上
#                         data_summary = None
#                         excel_file = next((f for f in data_files if f['name'].endswith('.xlsx') and f['name'].startswith(file_prefix)), None)
#                         if excel_file:
#                             try:
#                                 import pandas as pd
#                                 excel_path = os.path.join(report_dir, excel_file['name'])
#                                 df = pd.read_excel(excel_path, sheet_name="统计分析")
#                                 data_summary = df.to_html(classes="table table-striped", index=False)
#                             except Exception as e:
#                                 data_summary = f"无法读取Excel数据: {str(e)}"
                        
#                         # 获取报告目录的相对路径用于下载链接
#                         report_base = os.path.basename(report_dir)
                        
#                         # 添加报告信息到上下文
#                         context.update({
#                             'has_report': True,
#                             'report_dir': report_base,
#                             'report_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
#                             'keyword': keyword,
#                             'report_files': report_files,
#                             'chart_files': chart_files,
#                             'data_files': data_files,
#                             'log_summary': log_summary,
#                             'data_summary': data_summary,
                            
#                             # 主要图表
#                             'price_chart': price_chart,
#                             'price_ranges_chart': price_ranges_chart,
#                             'rating_chart': rating_chart,
#                             'rating_price_chart': rating_price_chart,
#                             'wordcloud': wordcloud,
#                             'top_keywords_chart': top_keywords_chart,
#                             'sentiment_chart': sentiment_chart,
                            
#                             # 导出选项
#                             'download_formats': [
#                                 {
#                                     'format': 'zip',
#                                     'name': 'ZIP归档(包含所有图表和日志)',
#                                     'url': reverse('admin:download-report', args=[report_base, 'zip'])
#                                 },
#                                 {
#                                     'format': 'pdf',
#                                     'name': 'PDF报告',
#                                     'url': reverse('admin:download-report', args=[report_base, 'pdf'])
#                                 },
#                                 {
#                                     'format': 'excel',
#                                     'name': 'Excel数据表',
#                                     'url': reverse('admin:download-report', args=[report_base, 'excel'])
#                                 }
#                             ]
#                         })
                        
#                         messages.success(request, f"已成功生成'{keyword}'的分析报告")
#                     else:
#                         messages.error(request, f"未能生成'{keyword}'的分析报告，可能没有相关数据。")
                
#                 except Exception as e:
#                     # 详细记录异常信息
#                     import traceback
#                     error_details = traceback.format_exc()
#                     messages.error(request, f"生成报告时出错: {str(e)}\n{error_details}")
#         else:
#             form = KeywordAnalysisForm()
        
#         context['form'] = form
        
#         # 检查模板目录并创建模板
#         template_path = os.path.join(settings.BASE_DIR, 'app', 'templates', 'admin')
#         os.makedirs(template_path, exist_ok=True)
        
#         # 创建模板文件
#         template_file = os.path.join(template_path, 'keyword_analysis.html')
#         if not os.path.exists(template_file):
#             with open(template_file, 'w', encoding='utf-8') as f:
#                 f.write('''{% extends "admin/base_site.html" %}
# {% load i18n admin_urls static %}

# {% block extrastyle %}
#   {{ block.super }}
#   <style type="text/css">
#     .form-row {
#       margin-bottom: 15px;
#     }
#     .help-text {
#       color: #666;
#       font-size: 0.9em;
#       margin-top: 5px;
#     }
#     .report-section {
#       margin-top: 20px;
#       padding: 15px;
#       background-color: #f5f5f5;
#       border-radius: 4px;
#     }
#     .report-summary {
#       display: flex;
#       flex-wrap: wrap;
#       gap: 15px;
#       margin-top: 15px;
#     }
#     .summary-card {
#       flex: 1;
#       min-width: 250px;
#       padding: 10px;
#       border: 1px solid #ddd;
#       border-radius: 4px;
#       background-color: white;
#     }
#     .summary-card img {
#       max-width: 100%;
#       height: auto;
#     }
#     .report-charts {
#       margin-top: 30px;
#     }
#     .chart-section {
#       margin-bottom: 30px;
#       background-color: white;
#       padding: 15px;
#       border-radius: 4px;
#       box-shadow: 0 1px 3px rgba(0,0,0,0.1);
#     }
#     .chart-section h3 {
#       margin-top: 0;
#       padding-bottom: 10px;
#       border-bottom: 1px solid #eee;
#     }
#     .chart-full {
#       width: 100%;
#       max-width: 1000px;
#       margin: 0 auto;
#     }
#     .chart-full img {
#       width: 100%;
#       height: auto;
#     }
#     .data-section {
#       margin-top: 30px;
#       background-color: white;
#       padding: 15px;
#       border-radius: 4px;
#       box-shadow: 0 1px 3px rgba(0,0,0,0.1);
#     }
#     .table {
#       width: 100%;
#       border-collapse: collapse;
#     }
#     .table th, .table td {
#       padding: 8px;
#       text-align: left;
#       border-bottom: 1px solid #ddd;
#     }
#     .table th {
#       background-color: #f2f2f2;
#     }
#     .table-striped tbody tr:nth-of-type(odd) {
#       background-color: #f9f9f9;
#     }
#     .export-options {
#       margin-top: 20px;
#     }
#     .button-group {
#       display: flex;
#       flex-wrap: wrap;
#       gap: 10px;
#       margin-top: 10px;
#     }
#     .error-message {
#       color: #c00;
#       font-weight: bold;
#     }
#     .log-summary {
#       background-color: #f8f9fa;
#       padding: 15px;
#       border-radius: 4px;
#       white-space: pre-wrap;
#       font-family: monospace;
#       margin-top: 20px;
#     }
#     .report-tabs {
#       margin-top: 20px;
#     }
#     .report-tabs .tab {
#       display: inline-block;
#       padding: 10px 15px;
#       cursor: pointer;
#       border: 1px solid #ddd;
#       border-bottom: none;
#       border-radius: 4px 4px 0 0;
#       background-color: #f2f2f2;
#       margin-right: 5px;
#     }
#     .report-tabs .tab.active {
#       background-color: white;
#       border-bottom: 1px solid white;
#       margin-bottom: -1px;
#     }
#     .tab-content {
#       border: 1px solid #ddd;
#       padding: 15px;
#       border-radius: 0 4px 4px 4px;
#       background-color: white;
#     }
#     .tab-pane {
#       display: none;
#     }
#     .tab-pane.active {
#       display: block;
#     }
#   </style>
# {% endblock %}

# {% block breadcrumbs %}
# <div class="breadcrumbs">
#   <a href="{% url 'admin:index' %}">首页</a> &rsaquo;
#   <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a> &rsaquo;
#   <a href="{% url 'admin:index' %}">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
#   产品关键词分析
# </div>
# {% endblock %}

# {% block content %}
# <div id="content-main">
#   <h1>产品关键词分析</h1>
  
#   <div class="module">
#     <form method="post">
#       {% csrf_token %}
#       <div class="form-row">
#         <label for="id_keyword">{{ form.keyword.label }}:</label>
#         {{ form.keyword }}
#         <div class="help-text">{{ form.keyword.help_text }}</div>
#       </div>
      
#       <div class="form-row">
#         <label for="id_days">{{ form.days.label }}:</label>
#         {{ form.days }}
#         <div class="help-text">{{ form.days.help_text }}</div>
#       </div>
      
#       <div class="form-row">
#         <label for="id_limit">{{ form.limit.label }}:</label>
#         {{ form.limit }}
#         <div class="help-text">{{ form.limit.help_text }}</div>
#       </div>
      
#       <div class="form-row">
#         <label for="id_export_format">{{ form.export_format.label }}:</label>
#         {{ form.export_format }}
#         <div class="help-text">{{ form.export_format.help_text }}</div>
#       </div>
      
#       <div class="submit-row">
#         <input type="submit" value="生成分析报告" class="default">
#       </div>
#     </form>
#   </div>
  
#   {% if has_report %}
#   <div class="report-section">
#     <h2>"{{ keyword }}"产品分析报告</h2>
#     <p>报告生成时间: {{ report_date }}</p>
    
#     <div class="report-summary">
#       {% if price_chart %}
#       <div class="summary-card">
#         <h3>价格分析</h3>
#         <img src="{{ price_chart.url }}" alt="价格分布图">
#       </div>
#       {% endif %}
      
#       {% if rating_chart %}
#       <div class="summary-card">
#         <h3>评分分析</h3>
#         <img src="{{ rating_chart.url }}" alt="评分分布图">
#       </div>
#       {% endif %}
      
#       {% if wordcloud %}
#       <div class="summary-card">
#         <h3>关键词分析</h3>
#         <img src="{{ wordcloud.url }}" alt="关键词云">
#       </div>
#       {% endif %}
#     </div>
    
#     <!-- 数据摘要部分 -->
#     <div class="data-section">
#       <h3>数据摘要</h3>
      
#       {% if data_summary %}
#         {{ data_summary|safe }}
#       {% else %}
#         {% if log_summary %}
#           <div class="log-summary">{{ log_summary }}</div>
#         {% else %}
#           <p>暂无数据摘要可显示</p>
#         {% endif %}
#       {% endif %}
#     </div>
    
#     <!-- 带标签页的完整报告 -->
#     <div class="report-tabs">
#       <div class="tab active" data-tab="price">价格分析</div>
#       <div class="tab" data-tab="rating">评分分析</div>
#       <div class="tab" data-tab="keywords">关键词分析</div>
#       <div class="tab" data-tab="sentiment">情感分析</div>
#     </div>
    
#     <div class="tab-content">
#       <!-- 价格分析标签页 -->
#       <div class="tab-pane active" id="price-tab">
#         {% if price_chart %}
#         <div class="chart-section">
#           <h3>价格分布图</h3>
#           <div class="chart-full">
#             <img src="{{ price_chart.url }}" alt="价格分布图">
#           </div>
#         </div>
#         {% endif %}
        
#         {% if price_ranges_chart %}
#         <div class="chart-section">
#           <h3>价格区间分布</h3>
#           <div class="chart-full">
#             <img src="{{ price_ranges_chart.url }}" alt="价格区间分布">
#           </div>
#         </div>
#         {% endif %}
#       </div>
      
#       <!-- 评分分析标签页 -->
#       <div class="tab-pane" id="rating-tab">
#         {% if rating_chart %}
#         <div class="chart-section">
#           <h3>评分分布图</h3>
#           <div class="chart-full">
#             <img src="{{ rating_chart.url }}" alt="评分分布图">
#           </div>
#         </div>
#         {% endif %}
        
#         {% if rating_price_chart %}
#         <div class="chart-section">
#           <h3>评分与价格关系</h3>
#           <div class="chart-full">
#             <img src="{{ rating_price_chart.url }}" alt="评分与价格关系">
#           </div>
#         </div>
#         {% endif %}
#       </div>
      
#       <!-- 关键词分析标签页 -->
#       <div class="tab-pane" id="keywords-tab">
#         {% if wordcloud %}
#         <div class="chart-section">
#           <h3>标题关键词云</h3>
#           <div class="chart-full">
#             <img src="{{ wordcloud.url }}" alt="标题关键词云">
#           </div>
#         </div>
#         {% endif %}
        
#         {% if top_keywords_chart %}
#         <div class="chart-section">
#           <h3>热门关键词统计</h3>
#           <div class="chart-full">
#             <img src="{{ top_keywords_chart.url }}" alt="热门关键词统计">
#           </div>
#         </div>
#         {% endif %}
#       </div>
      
#       <!-- 情感分析标签页 -->
#       <div class="tab-pane" id="sentiment-tab">
#         {% if sentiment_chart %}
#         <div class="chart-section">
#           <h3>情感分析结果</h3>
#           <div class="chart-full">
#             <img src="{{ sentiment_chart.url }}" alt="情感分析结果">
#           </div>
#         </div>
#         {% endif %}
#       </div>
#     </div>
    
#     <div class="export-options">
#       <h3>导出报告</h3>
#       <div class="button-group">
#         {% for format in download_formats %}
#         <a href="{{ format.url }}" class="button" target="_blank">
#           下载{{ format.name }}
#         </a>
#         {% endfor %}
#       </div>
#     </div>
#   </div>
  
#   <!-- 标签页切换脚本 -->
#   <script type="text/javascript">
#     document.addEventListener('DOMContentLoaded', function() {
#       var tabs = document.querySelectorAll('.tab');
      
#       tabs.forEach(function(tab) {
#         tab.addEventListener('click', function() {
#           // 移除所有标签和内容的活动状态
#           document.querySelectorAll('.tab').forEach(function(t) {
#             t.classList.remove('active');
#           });
          
#           document.querySelectorAll('.tab-pane').forEach(function(p) {
#             p.classList.remove('active');
#           });
          
#           // 添加当前标签和内容的活动状态
#           this.classList.add('active');
#           var tabName = this.getAttribute('data-tab');
#           document.getElementById(tabName + '-tab').classList.add('active');
#         });
#       });
#     });
#   </script>
#   {% endif %}
# </div>
# {% endblock %}
# ''')
        
#         return render(request, 'admin/keyword_analysis.html', context)

# 注册到 admin
# admin.site.register(ProductKeywordAnalysis, ProductKeywordAnalysisAdmin)
@admin.register(CategoryXue)
class CategoryXueAdmin(admin.ModelAdmin):
    list_display = ['category', 'parent_category', 'parent_level', 'level', 'url', 'image_url', 'alt_text', 'currentpage', 'opdate','need_download','leaf_category']  # 假设这些字段存在于模型中
    search_fields = ['category', 'parent_category', 'parent_level', 'level', 'url', 'image_url', 'alt_text', 'currentpage', 'opdate']

# 注册 RankChange 模型
@admin.register(RankChange)
class RankChangeAdmin(DepartmentFilteredModelAdmin):
    list_display = ['productid', 'old_main_rank', 'new_main_rank', 'old_sub_rank', 'new_sub_rank', 
                    'old_sales_info', 'new_sales_info', 'old_rating', 'new_rating', 
                    'old_reviews_count', 'new_reviews_count', 'epid', 'opdate']
    list_filter = ['opdate']
    search_fields = ['productid']
    
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display

# 注册 PriceChange 模型
@admin.register(PriceChange)
class PriceChangeAdmin(DepartmentFilteredModelAdmin):
    list_display = ['productid', 'old_price', 'new_price', 'epid', 'opdate']
    list_filter = ['opdate']
    search_fields = ['productid']
    
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display

@admin.register(asinsupload_xue)
class asinsupload_xueAdmin(DepartmentFilteredModelAdmin):
    list_display = ['id', 'asin', 'brand','epid', 'display_pic', 'category1', 'rank1','category2', 'rank2',  'opdate', 'processdate',
                    'detail1', 'detail2', 'detail3', 'detail4', 'detail5']
    list_filter = ['opdate', 'processdate']
    search_fields = ['asin']
    change_list_template = "admin/app_asinupload_xue_changelist.html"  # 自定义模板
    exclude = ['epid']
    fieldsets = (

        ('基本信息', {
            'fields': ('asin', 'detail1', 'detail2', 'detail3', 'detail4', 'detail5')
        }),
    )
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display

    def get_queryset(self, request):
        """只显示当前用户所属部门的数据"""
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs  # 超级用户查看所有数据
        if hasattr(request.user, 'profile') and hasattr(request.user.profile, 'epid'):
            return qs.filter(epid=request.user.profile.epid)
        return qs.none()  # 如果用户没有部门，返回空查询集
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_model(request, obj, form, change)
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display
    
    def build_full_url(self, url):
        # 这里应该是将路径转换为完整 URL 的逻辑，需要根据实际情况实现
        return url
    
    def display_pic(self, obj):
        """显示图片"""
        if obj.image_url:
            full_url = self.build_full_url(obj.image_url)
            return format_html('<img src="{}" style="max-height: 50px;" />', full_url)
        return "无图片"
    
    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return True

    def has_view_permission(self, request, obj=None):
        return True

    def has_add_permission(self, request):
        return True

        
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('import_excel_asinupload/', self.admin_site.admin_view(self.import_excel_asinupload), name='import_excel_asinupload'),
            path('fetch-amazon-data/', self.admin_site.admin_view(self.fetch_amazon_data), name='fetch_amazon_data'),

        ]
        return custom_urls + urls
    
    def fetch_amazon_data(self, request):
        # 调用你的函数来访问亚马逊并写入数据库
        # if request.session.get('data_downloaded', False):
        request.session['data_downloaded'] = True
        self.message_user(request, "开始下载亚马逊数据，如果退出网页，则下载停止。")

        fetch_amazon_data_interface(Amazon_asinupload_xue_todb,self,request)
        self.message_user(request, "数据已成功从亚马逊下载并写入数据库。")
        request.session['data_downloaded'] = False
        # else:
        #     self.message_user(request, "已经在下载，无法重复下载任务，如果想重新下载，请注销后重新登录.刷新，关闭浏览器都无效")
        
        return HttpResponseRedirect(request.META.get('HTTP_REFERER'))  # 重定向回原页面    
    def import_excel_asinupload(self, request):
        if request.method == 'POST':
            form = ImportExcelForm(request.POST, request.FILES)
            if form.is_valid():
                excel_file = request.FILES['excel_file']
                try:
                    df = pd.read_excel(excel_file)
                    total_rows = len(df)
                    asins = []
                    for index, row in df.iterrows():
                        asin = ''
                        value_to_insert = row[0]
                        asin = value_to_insert
                        # 添加当前用户的部门编号
                        epid = request.user.profile.epid if hasattr(request.user, 'profile') else 'default'
                        asins.append({'asin': asin, 'epid': epid})
                        print(index, asin, '/', total_rows)

                    try:
                        # 使用 bulk_create 批量创建记录
                        sql = '''
                          insert into app_asinsupload_xue(asin, epid, opdate) 
                          values(:asin, :epid, now()) 
                          on DUPLICATE key update asin=:asin, epid=:epid, opdate=now()
                        '''
                        db_config = {
                            "user": "root",
                            "password": "Zb_200407",
                            "host": "gz-cdb-d4j7h16x.sql.tencentcdb.com",
                            "database": "walmart",
                            "port": 22333
                        }
                        connection_string = (
                            f"mysql+pymysql://{db_config['user']}:{db_config['password']}"
                            f"@{db_config['host']}:{db_config['port']}/{db_config['database']}?connect_timeout=10"
                        )
                        engine1 = create_engine(connection_string, pool_recycle=3600)
                        with engine1.connect() as connection:
                            connection.execute(text(sql), asins)    
                            connection.commit()           
                        
                        messages.success(request, f'成功处理 {len(asins)} 条记录')
                    except Exception as e:
                        messages.error(request, f'处理记录时出错: {str(e)}')
                        traceback.print_exc()

                    messages.success(request, 'Excel 文件导入成功')
                    return redirect('..')
                except Exception as e:
                    messages.error(request, f'Excel文件处理失败: {e}')
                    traceback.print_exc()

        else:
            form = ImportExcelForm()

        context = {
            'form': form,
        }
        return TemplateResponse(request, "admin/import_excel.html", context)

@admin.register(asinsmonitor_xue)
class asinsmonitor_xueAdmin(DepartmentFilteredModelAdmin):
    list_display = ['id', 'asin', 'epid', 'hoursdiff', 'opdate']
    list_filter = ['opdate', 'hoursdiff']
    search_fields = ['asin']  
    change_list_template = "admin/app_asinmonitor_xue_changelist.html"  # 自定义模板
    exclude = ['epid']
    fieldsets = (
        ('基本信息', {
            'fields': ('asin', 'hoursdiff' )
        }),
    )
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display

    def get_queryset(self, request):
        """只显示当前用户所属部门的数据"""
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs  # 超级用户查看所有数据
        if hasattr(request.user, 'profile') and hasattr(request.user.profile, 'epid'):
            return qs.filter(epid=request.user.profile.epid)
        return qs.none()  # 如果用户没有部门，返回空查询集
    def save_model(self, request, obj, form, change):
        """创建新记录时自动设置部门字段为当前用户部门"""
        if not change:  # 只在创建新记录时设置
            if hasattr(request.user, 'profile'):
                obj.epid = request.user.profile.epid
        super().save_model(request, obj, form, change)
    def get_list_display(self, request):
        """如果不是超级用户，则不显示epid字段"""
        list_display = list(super().get_list_display(request))
        if not request.user.is_superuser and 'epid' in list_display:
            list_display.remove('epid')
        return list_display
    
    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return True

    def has_view_permission(self, request, obj=None):
        return True

    def has_add_permission(self, request):
        return True

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('import_excel_asinsmonitor/', self.admin_site.admin_view(self.import_excel_asinsmonitor), name='import_excel_asinsmonitor'),
        ]
        return custom_urls + urls
        
    def import_excel_asinsmonitor(self, request):
        if request.method == 'POST':
            form = ImportExcelForm(request.POST, request.FILES)
            if form.is_valid():
                excel_file = request.FILES['excel_file']
                try:
                    df = pd.read_excel(excel_file)
                    total_rows = len(df)
                    asins = []
                    for index, row in df.iterrows():
                        asin = ''
                        value_to_insert = row[0]
                        asin = value_to_insert
                        # 添加当前用户的部门编号
                        epid = request.user.profile.epid if hasattr(request.user, 'profile') else 'default'
                        hoursdiff = 2  # 默认监控频率
                        asins.append({'asin': asin, 'epid': epid, 'hoursdiff': hoursdiff})
                        print(index, asin, '/', total_rows)
                   
                    try:
                        # 使用 bulk_create 批量创建记录
                        sql = '''
                          insert into app_asinsmonitor_xue(asin, epid, hoursdiff, opdate) 
                          values(:asin, :epid, :hoursdiff, now()) 
                          on DUPLICATE key update asin=:asin, epid=:epid, opdate=now()
                        '''
                        db_config = {
                            "user": "root",
                            "password": "Zb_200407",
                            "host": "gz-cdb-d4j7h16x.sql.tencentcdb.com",
                            "database": "walmart",
                            "port": 22333
                        }
                        connection_string = (
                            f"mysql+pymysql://{db_config['user']}:{db_config['password']}"
                            f"@{db_config['host']}:{db_config['port']}/{db_config['database']}?connect_timeout=10"
                        )
                        engine1 = create_engine(connection_string, pool_recycle=3600)
                        with engine1.connect() as connection:
                            connection.execute(text(sql), asins)
                            connection.commit()
                        
                        messages.success(request, f'成功处理 {len(asins)} 条记录')
                    except Exception as e:
                        messages.error(request, f'处理记录时出错: {str(e)}')
                        traceback.print_exc()

                    messages.success(request, 'Excel 文件导入成功')
                    return redirect('..')
                except Exception as e:
                    messages.error(request, f'Excel文件处理失败: {e}')
                    traceback.print_exc()

        else:
            form = ImportExcelForm()

        context = {
            'form': form,
        }
        return TemplateResponse(request, "admin/import_excel.html", context)

# 自定义User管理界面，添加部门编号
class UserProfileInline(admin.StackedInline):
    model = UserProfile
    can_delete = False
    verbose_name = '部门信息'
    verbose_name_plural = '部门信息'
    readonly_fields = ('created_at', 'updated_at')
    
class CustomUserAdmin(BaseUserAdmin):
    form = CustomUserChangeForm
    add_form = CustomUserCreationForm
    inlines = (UserProfileInline,)
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'get_epid')
    list_filter = BaseUserAdmin.list_filter + ('profile__epid',)
    
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        ('个人信息', {'fields': ('first_name', 'last_name', 'email', 'epid')}),
        ('权限', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
        ('重要日期', {'fields': ('last_login', 'date_joined')}),
    )
    
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'password1', 'password2', 'epid', 'is_staff', 'is_superuser')
        }),
    )
    
    def get_epid(self, obj):
        if hasattr(obj, 'profile'):
            return obj.profile.epid
        return '-'
    get_epid.short_description = '部门编号'
    
    def save_model(self, request, obj, form, change):
        """保存User模型时同时更新或创建UserProfile"""
        super().save_model(request, obj, form, change)
        
        # 获取表单中的epid值
        epid = form.cleaned_data.get('epid', 'default')
        
        # 更新或创建用户的profile
        if hasattr(obj, 'profile'):
            # 更新现有profile
            profile = obj.profile
            profile.epid = epid
            profile.save()
        else:
            # 创建新profile
            from app.models import UserProfile
            UserProfile.objects.create(user=obj, epid=epid)
            
    def get_inline_instances(self, request, obj=None):
        # 新建用户时不显示内联表单，因为我们会在save_model中创建
        if not obj:
            return []
        return super().get_inline_instances(request, obj)

# 取消注册原有的User管理界面
admin.site.unregister(User)
# 注册自定义的User管理界面
admin.site.register(User, CustomUserAdmin)

# 部门筛选的基础ModelAdmin类

@admin.register(AmazonProductDisplay)
class AmazonProductAdmin(BaseAdmin):
    list_display = [
        'asin1', 
        'item_name', 
        'seller_sku','quantity','product_id','fulfillment_channel', 
        'display_image',
        'status','bullet_point1','brand','item_type_keywords','item_package_dimensions','item_package_weight','number_of_items','material','battery_required',
        'updated_at'
    ]
    def display_image(self, obj):
        if obj.image_url:  # 确保 image_url 不为空
            return format_html('<img src="{}" style="width: 100px; height: auto;" />', obj.image_url)
        return "无图片"  # 如果没有图片，返回一个默认值

    display_image.short_description = '图片'  # 设置列标题
    list_filter = [   'status' ]
    search_fields = ['asin1',   'item_name' ]
    readonly_fields = ['asin1',  'updated_at']
    
    fieldsets = (
        ('基本信息', {
            'fields': (
                'asin1', 'seller_sku', 'item_name', 'image_url' 
            )
        }),
        ('价格信息', {
            'fields': (
                'standard_price', 'currency' 
            )
        }),
        ('产品详情', {
            'fields': (
                'bullet_points', 'item_description'
            )
        }),
        ('图片信息', {
            'fields': (
                'main_image_url', 'image_urls'
            )
        }),
        
        ('时间信息', {
            'fields': (
                'updated_at',
            )
        }),
    )
     



class LogHistoryAdmin(admin.ModelAdmin):
    list_display = ('obj', 'action', 'opdate', 'diskid')  # 显示的字段

    def get_queryset(self, request):
        # 记录日志
        LogHistory.objects.create(
            obj=request.path,  # 记录访问的页面路径
            action='访问',  # 记录操作类型
            opdate=datetime.now(),  # 当前时间
            diskid=request.user.id if request.user.is_authenticated else None  # 记录用户 ID
        )
        return super().get_queryset(request)

# 注册 LogHistory 模型
admin.site.register(LogHistory, LogHistoryAdmin)

AMAZON_CLIENT_ID = '你的client_id'
AMAZON_CLIENT_SECRET = '你的client_secret'
AMAZON_REDIRECT_URI = 'https://你的域名/amazon/callback/'

@admin.register(AmazonStore)
class AmazonStoreAdmin(admin.ModelAdmin):
    list_display = ('store_name', 'seller_id', 'account', 'country', 'auth_status', 'store_status', 'last_auth_time', 'get_auth_button')
    search_fields = ('store_name', 'seller_id', 'account', 'country')
    list_filter = ('auth_status', 'store_status', 'country')
    fieldsets = (
        ('基本信息', {
            'fields': ('store_name', 'seller_id', 'account', 'country')
        }),
        ('授权信息', {
            'fields': ('auth_status', 'store_status', 'last_auth_time')
        }),
    )
    
    def get_auth_button(self, obj):
        if obj.auth_status == 'success':
            return format_html(
                '<span style="color: green;">已授权</span>'
            )
        else:
            return format_html(
                '<a class="button" href="{}">授权</a>',
                reverse('admin:amazon-auth', args=[obj.id])
            )
    get_auth_button.short_description = '授权状态'
    
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path(
                '<int:store_id>/auth/',
                self.admin_site.admin_view(self.amazon_auth_view),
                name='amazon-auth',
            ),
            path(
                'callback/',
                self.admin_site.admin_view(self.amazon_auth_callback),
                name='amazon-auth-callback',
            ),
            path(
                'amazon-auth/<int:store_id>/',
                self.admin_site.admin_view(self.amazon_auth_view),
                name='amazon_auth_view',
            ),
        ]
        return custom_urls + urls
   
    def amazon_auth_view(self, request, store_id):
        store = AmazonStore.objects.get(pk=store_id)
        # 假设 store.sites 是 ['us', 'ca', 'mx', 'br'] 这样的列表
        ALL_SITE_CHOICES = [
            ('us', '美国'),
            ('ca', '加拿大'),
            ('mx', '墨西哥'),
            ('br', '巴西'),
            ('uk', '英国'),
            ('de', '德国'),
            ('fr', '法国'),
            ('it', '意大利'),
            ('es', '西班牙'),
            ('jp', '日本'),
            ('au', '澳大利亚'),
            # ...如有更多请补充...
            ]
        # 选中的站点
 
        selected_sites = store.sites if hasattr(store, 'sites') else ['us', 'ca', 'mx', 'br']
        if 'go' in request.POST:
            # 这里填写你的亚马逊授权跳转URL
            amazon_url = 'https://sellercentral.amazon.com/apps/authorize/consent?...'
            return redirect(amazon_url)
        else:

            return render(request, 'admin/amazon_auth_confirm.html', {
                'store_id': store_id,
                'account_name': store.store_name,
                'region': store.region,
                'all_sites': ALL_SITE_CHOICES,
                'selected_sites': ALL_SITE_CHOICES,  
            })
    
    def get_amazon_auth_url(self, client_id, redirect_uri, state):
        base_url = "https://sellercentral.amazon.com/apps/authorize/consent"
        params = {
            "application_id": client_id,
            "state": state,
            "redirect_uri": redirect_uri,
            "version": "beta"
        }
        return f"{base_url}?{urllib.parse.urlencode(params)}"
    
    def amazon_auth_callback(self, request):
        # 验证state防止CSRF攻击
        stored_state = request.session.get('amazon_auth_state')
        received_state = request.GET.get('state')
        
        if not stored_state or stored_state != received_state:
            messages.error(request, '授权验证失败')
            return redirect('..')
            
        store_id = request.session.get('amazon_store_id')
        if not store_id:
            messages.error(request, '店铺信息丢失')
            return redirect('..')
            
        store = self.get_object(request, store_id)
        if not store:
            messages.error(request, '店铺不存在')
            return redirect('..')
            
        code = request.GET.get('spapi_oauth_code')
        selling_partner_id = request.GET.get('selling_partner_id')
        
        if not code or not selling_partner_id:
            messages.error(request, '授权参数不完整')
            return redirect('..')
            
        try:
            # 获取访问令牌
            token_url = "https://api.amazon.com/auth/o2/token"
            data = {
                "grant_type": "authorization_code",
                "code": code,
                "client_id": store.app_config.client_id,
                "client_secret": store.app_config.client_secret,
                "redirect_uri": store.app_config.redirect_uri,
            }
            
            response = requests.post(token_url, data=data)
            response.raise_for_status()
            token_data = response.json()
            
            # 更新店铺信息
            store.refresh_token = token_data.get('refresh_token')
            store.access_token = token_data.get('access_token')
            store.auth_status = 'success'
            store.last_auth_time = timezone.now()
            store.save()
            
            messages.success(request, '授权成功')
            
        except requests.exceptions.RequestException as e:
            messages.error(request, f'获取访问令牌失败: {str(e)}')
            store.auth_status = 'fail'
            store.save()
            
        except Exception as e:
            messages.error(request, f'授权过程出错: {str(e)}')
            store.auth_status = 'fail'
            store.save()
            
        finally:
            # 清理session
            request.session.pop('amazon_auth_state', None)
            request.session.pop('amazon_store_id', None)
            
        return redirect('..')

@admin.register(AmazonAppConfig)
class AmazonAppConfigAdmin(admin.ModelAdmin):
    list_display = ('app_name', 'client_id', 'redirect_uri', 'is_active', 'updated_at')
    fieldsets = (
        ('应用配置', {
            'fields': ('app_name', 'client_id', 'client_secret', 'redirect_uri', 'is_active'),
            'description': '请填写从亚马逊开发者平台获取的应用信息。这是全局配置，所有店铺将共用此配置。'
        }),
    )
    readonly_fields = ('created_at', 'updated_at')

    def has_add_permission(self, request):
        # 如果没有配置实例，允许添加
        if not AmazonAppConfig.objects.exists():
            return True
        return False

    def has_delete_permission(self, request, obj=None):
        # 不允许删除配置
        return False

    def get_actions(self, request):
        # 移除批量删除操作
        actions = super().get_actions(request)
        if 'delete_selected' in actions:
            del actions['delete_selected']
        return actions

    def changelist_view(self, request, extra_context=None):
        # 如果已经有配置，直接跳转到编辑页面
        if AmazonAppConfig.objects.exists():
            config = AmazonAppConfig.objects.first()
            return redirect('admin:app_amazonappconfig_change', config.id)
        return super().changelist_view(request, extra_context)

# ... existing code ... 

@admin.register(Product2)
class ProductAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'sku', 'price', 'stock', 'created_at', 'updated_at')
    search_fields = ('name', 'sku')
    list_filter = ('created_at',)